package com.pjmike.netty.protocol.message.decoder;

import com.pjmike.netty.protocol.message.command.Command;
import com.pjmike.netty.protocol.message.packet.request.AuthRequestPacket;
import com.pjmike.netty.protocol.message.packet.request.TrafficDataRequestPacket;
import com.pjmike.netty.protocol.message.packet.request.VO.*;
import com.pjmike.netty.utils.Crc32Util;
import com.pjmike.netty.utils.DataTransformUtil;
import com.pjmike.netty.utils.StringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.zip.CRC32;
import java.util.ArrayList;
import java.util.List;

/**
 *车流编码器
 *
 * @author lujunjie
 * @create 2021-01-09 09:10
 */
@Slf4j
public class TrafficDataDecoder extends ByteToMessageDecoder {
    //认证报文长度
//    private static int MESSAGE_LENGTH = ;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (!check(in)) {
            log.error("车流参数检验到非法报文，{}", StringUtil.getByteBufByteHexString(in));
            return;
        }
        in.markReaderIndex();
        short header = in.readUnsignedByte();
        int protocolNo = in.readUnsignedShort();
        if (protocolNo == Command.TRAFFIC_DATA_REQUEST) {
            TrafficDataRequestPacket trafficDataRequestPacket = new TrafficDataRequestPacket();
            //1、报文头
            trafficDataRequestPacket.setBt(header);
            //2、协议号
            trafficDataRequestPacket.setProtocolNo(protocolNo);
            //3、设备编号
            byte[] sbbhbytes = new byte[15];
            in.readBytes(sbbhbytes);
            trafficDataRequestPacket.setSbbh(new String(sbbhbytes, 0, 15));
            //4、数据长度
            long sjcd = in.readUnsignedInt();
            trafficDataRequestPacket.setSjcd(sjcd);
            //5、统计编号
            byte[] tjidbytes = new byte[32];
            in.readBytes(tjidbytes);
            trafficDataRequestPacket.setTjid(new String(tjidbytes, 0, 32));
            //6、统计开始时间
            long tjkssjbytes = in.readUnsignedInt();
            trafficDataRequestPacket.setTjkssl(tjkssjbytes);
            //7、统计结束时间
            long tjjssjbytes = in.readUnsignedInt();
            trafficDataRequestPacket.setTjjssj(tjjssjbytes);
            //8、统计周期
            short tjzqbytes = in.readUnsignedByte();
            trafficDataRequestPacket.setTjzq(tjzqbytes);
            //9、车道数量
            short cdzsbytes = in.readUnsignedByte();
            trafficDataRequestPacket.setCdzs(cdzsbytes);
            List<TrafficDataVO> trafficDataVOList = new ArrayList<TrafficDataVO>();
            for (int i = 0; i < (int) cdzsbytes; i++) {
                TrafficDataVO trafficDataVO = new TrafficDataVO();
                //10、车道号
                byte[] cdhbytes = new byte[2];
                in.readBytes(cdhbytes);
                trafficDataVO.setCdh(new String(cdhbytes, 0, 2));
                //11、车道流量
                int cdllbytes = in.readUnsignedShort();
                trafficDataVO.setCdll(cdllbytes);
                //12、车道平均速度
                short cdpjsdbytes = in.readUnsignedByte();
                trafficDataVO.setCdpjsd(cdpjsdbytes);
                //13、车道平均占有率
                short cdpjzylbytes = in.readUnsignedByte();
                trafficDataVO.setCdpjzyl(cdpjzylbytes);
                //14、车道车头时距
                int ctsjbytes = in.readUnsignedShort();
                trafficDataVO.setCtsj(ctsjbytes);
                //15、进车道排队长度
                int jcdpdcdbytes = in.readUnsignedShort();
                trafficDataVO.setJcdpdcd(jcdpdcdbytes);
                //16、前方路口排队至出车道溢出距离
                int ccdjlbytes = in.readUnsignedShort();
                trafficDataVO.setCcdjl(ccdjlbytes);
                //17、前方路口排队至出车道进口溢出阀值距离
                int ccdycjlfzbytes = in.readUnsignedShort();
                trafficDataVO.setCcdycjlfz(ccdycjlfzbytes);
                //18、车型数
                short cxsbytes = in.readUnsignedByte();
                trafficDataVO.setCxs(cxsbytes);
                List<VehicleVO> vehicleVOList = new ArrayList<VehicleVO>();
                for (int j = 0; j < (int) cxsbytes; j++) {
                    VehicleVO vehicleVO = new VehicleVO();
                    //19、车型编号
                    short cxbhibytes = in.readUnsignedByte();
                    vehicleVO.setCxbhi(cxbhibytes);
                    //20、分车型流量
                    int cxllibytes = in.readUnsignedShort();
                    vehicleVO.setCxlli(cxllibytes);
                    //21、分车型平均速度
                    short cxpjsdibytes = in.readUnsignedByte();
                    vehicleVO.setCxpjsdi(cxpjsdibytes);
                    vehicleVOList.add(vehicleVO);
                }
                //22
                trafficDataVO.setVehicleVOList(vehicleVOList);
                trafficDataVOList.add(trafficDataVO);

            }
            trafficDataRequestPacket.setTrafficDataVOList(trafficDataVOList);
            //23 数据校验
            trafficDataRequestPacket.setSjjy(in.readUnsignedInt());
            //24、数据包尾
            trafficDataRequestPacket.setBw(in.readUnsignedByte());
            log.info("获取到车流报文，内容：{}", trafficDataRequestPacket);
            out.add(trafficDataRequestPacket);
        } else {
            in.resetReaderIndex();
            ByteBuf frame = in.retainedDuplicate();
            out.add(frame);
            in.skipBytes(in.readableBytes());
        }
    }

    /**
     * @return boolean
     * @Author bj
     * @Description //校验报文
     * @Date 11:54 2021/1/10
     * @Param [in]
     **/
    private boolean check(ByteBuf in) {
        return Crc32Util.checkMessageFromByteBuf(in);
    }
}
